#include "TcpConnection.h"
#include "EventLoop.h"
#include <iostream>
#include <sstream>

using std::ostringstream;

TcpConnection::TcpConnection(int fd, EventLoop *loop)
: _loop(loop)
, _sockIO(fd)
, _sock(fd)
, _localAddr(getLocalAddr())
, _peerAddr(getPeerAddr()){}


TcpConnection::~TcpConnection(){}


void TcpConnection::send(const pair<int, void*> &msg){
    _sockIO.sendMsg(msg);
}


void TcpConnection::sendInLoop(const pair<int, void*> &QueryRsult){
    if(_loop){
        // 将线程池处理好之后的 msg, 以及发送 msg 的能力 (也就是 TcpConnection 中的 send())都交给 EventLoop
        // 然后在 EventLoop 里面再去发送数据给客户端
        _loop->runInLoop(std::bind(&TcpConnection::send, this, QueryRsult));
    }
}


// 接收数据
string TcpConnection::receive(){
    char buff[1024] = {0};
    _sockIO.readMsg(buff);
    return string(buff);
}


// 查看对应的缓冲区中是否有数据
bool TcpConnection::isClosed() const{
    char buf[10] = {0};
    int ret = ::recv(_sock.fd(), buf, sizeof(buf), MSG_PEEK);
    return 0 == ret;
}


string TcpConnection::toString(){
    ostringstream oss;
    oss << _localAddr.ip() << ":"
        << _localAddr.port() << "---->"
        << _peerAddr.ip() << ":"
        << _peerAddr.port();

    return oss.str();
}


// 获取本端的网络地址信息
InetAddress TcpConnection::getLocalAddr(){
    struct sockaddr_in addr;
    socklen_t len = sizeof(struct sockaddr );
    // 获取本端地址的函数 getsockname() 
    int ret = getsockname(_sock.fd(), (struct sockaddr *)&addr, &len);
    if(-1 == ret){
        perror("getsockname");
    }
    return InetAddress(addr);
}


// 获取对端的网络地址信息
InetAddress TcpConnection::getPeerAddr(){
    struct sockaddr_in addr;
    socklen_t len = sizeof(struct sockaddr );
    // 获取对端地址的函数 getpeername() 
    int ret = getpeername(_sock.fd(), (struct sockaddr *)&addr, &len);
    if(-1 == ret){
        perror("getpeername");
    }
    return InetAddress(addr);
}


// 注册 Tcp 连接中的三个事件
void TcpConnection::setConnectionCallback(const TcpConnectionCallback &cb){
    _onConnectionCb = cb;
}


void TcpConnection::setMessageCallback(const TcpConnectionCallback &cb){
    _onMessageCb = cb;
}


void TcpConnection::setCloseCallback(const TcpConnectionCallback &cb){
    _onCloseCb = cb;
}


// 执行 Tcp 通信过程中的三个事件
void TcpConnection::handleConnectionCallback(){
    if(_onConnectionCb){
        // 为了防止指针的误用, 也就是防止不同的智能指针托管同一个裸指针
        /* _onConnectionCb(shared_ptr<TcpConnection>(this)); */
        _onConnectionCb(shared_from_this()); // 返回共享 *this 所有权的 shared_ptr
                                             // 多个 TCP 连接是共享这些回调的 
    }
}


void TcpConnection::handleMessageCallback(){
    if(_onMessageCb){
        _onMessageCb(shared_from_this());
    }
}


void TcpConnection::handleCloseCallback(){
    if(_onCloseCb){
        _onCloseCb(shared_from_this());
    }
}
